package org.zjt.chapter1.monitor;

import com.sun.corba.se.pept.transport.ByteBufferPool;

import sun.misc.JavaNioAccess;

import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Description:
 *
 * @author juntao.zhang
 * Date: 2018-11-30 4:38 PM
 * @see  java.nio.Bits#reservedMemory 已经使用的了
 *       java.nio.Bits#totalCapacity  总内存
 */
public class JdkDirectMemoryMonitor {

    private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

    private AtomicLong reservedMemory ;

    private AtomicLong totalCapacity ;


    public JdkDirectMemoryMonitor() throws Exception{
        Class clazz = Class.forName("java.nio.Bits");
        
        Field reservedMemoryField = clazz.getDeclaredField("reservedMemory");
        Field totalCapacityField = clazz.getDeclaredField("totalCapacity");
        reservedMemoryField.setAccessible(true);
        totalCapacityField.setAccessible(true);

        reservedMemory = (AtomicLong) reservedMemoryField.get(clazz);
        totalCapacity = (AtomicLong) totalCapacityField.get(clazz);
    }


    public void startup(){
        executor.scheduleAtFixedRate(()-> System.out.printf("reservedMemory:%s M     totalCapacity:%s M \n",reservedMemory.get() / (1 << 20),totalCapacity.get() / (1 << 20)),0,1, TimeUnit.SECONDS);
    }

    public void shutdown(){
        executor.shutdown();
    }

    public static void main(String[] args) throws Exception {
        JdkDirectMemoryMonitor jdkDirectMemoryMonitor = new JdkDirectMemoryMonitor();
        jdkDirectMemoryMonitor.startup();


        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024);
        ByteBuffer.allocateDirect(1 << 20);
        TimeUnit.SECONDS.sleep(4);


        ByteBuffer.allocateDirect(1024);
        ByteBuffer.allocateDirect(1 << 20);
        TimeUnit.SECONDS.sleep(4);

        ByteBuffer.allocateDirect(1024);
        ByteBuffer.allocateDirect(10 << 20);
        TimeUnit.SECONDS.sleep(4);

        jdkDirectMemoryMonitor.shutdown();
    }

}
